package cn.demoncat.util.lang.entity.data;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
 * 多链表
 * 
 * @author 延晓磊
 *
 * @since 2020年7月24日
 */
public class MapLinkedList<E> {

	// 主数据
	private E data;
	// 链表集
	private final Map<String, SingleLinkedList<E>> map;
	
	// 内置选项
	private static final String LEFT = "L";
	private static final String CENTER = "C";
	private static final String RIGHT = "R";
	
	/**
	 * 构建
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月25日
	 */
	public MapLinkedList() {
		super();
		map = new LinkedHashMap<>();
	}

	/**
	 * 构建
	 * 
	 * @param size 链表数量
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月25日
	 */
	public MapLinkedList(int size) {
		super();
		map = new LinkedHashMap<>(size);
	}
	
	/**
	 * 主数据
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public E getData() {
		return data;
	}
	
	/**
	 * 主数据
	 * 
	 * @param data
	 * 
	 * @return 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public MapLinkedList<E> setData(E data) {
		this.data = data;
		return this;
	}
	
	/**
	 * 获取链表集
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public Map<String, SingleLinkedList<E>> getMap() {
		return map;
	}

	/**
	 * 获取链表
	 * 
	 * @param key 链表KEY
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public SingleLinkedList<E> getList(String key){
		SingleLinkedList<E> list = map.get(key);
		if (list == null) {
			list = new SingleLinkedList<>();
			map.put(key, list);
		}
		return list;
	}
	
	/**
	 * 获取Left链表
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public SingleLinkedList<E> getLeftList(){
		return getList(LEFT);
	}
	
	/**
	 * 获取Center链表
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public SingleLinkedList<E> getCenterList(){
		return getList(CENTER);
	}
	
	/**
	 * 获取Right链表
	 * 
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public SingleLinkedList<E> getRightList(){
		return getList(RIGHT);
	}
	
	/**
	 * 添加链表数据
	 * 
	 * @param key	链表KEY
	 * @param data	数据
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2020年7月24日
	 */
	public MapLinkedList<E> add(String key, E data) {
		getList(key).add(data);
		return this;
	}
	
	/**
	 * 添加Left链表数据
	 * 
	 * @param data	数据
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2020年7月24日
	 */
	public MapLinkedList<E> addLeft(E data) {
		return add(LEFT, data);
	}
	
	/**
	 * 添加Center链表数据
	 * 
	 * @param data	数据
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2020年7月24日
	 */
	public MapLinkedList<E> addCenter(E data) {
		return add(CENTER, data);
	}
	
	/**
	 * 添加Right链表数据
	 * 
	 * @param data	数据
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2020年7月24日
	 */
	public MapLinkedList<E> addRight(E data) {
		return add(RIGHT, data);
	}
	
	/**
	 * 删除链表数据
	 * 
	 * @param key	链表KEY
	 * @param data
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2020年7月24日
	 */
	public MapLinkedList<E> del(String key, E data) {
		getList(key).removeAll(data);
		return this;
	}
	
	/**
	 * 删除Left链表数据
	 * 
	 * @param data
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2020年7月24日
	 */
	public MapLinkedList<E> delLeft(E data) {
		return del(LEFT, data);
	}
	
	/**
	 * 删除Center链表数据
	 * 
	 * @param data
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2020年7月24日
	 */
	public MapLinkedList<E> delCenter(E data) {
		return del(CENTER, data);
	}
	
	/**
	 * 删除Right链表数据
	 * 
	 * @param data
	 * 
	 * @author 延晓磊
	 * @return 
	 *
	 * @since 2020年7月24日
	 */
	public MapLinkedList<E> delRight(E data) {
		return del(RIGHT, data);
	}
	
	/**
	 * 查找链表数据
	 * 
	 * @param key	链表KEY
	 * @param data	数据
	 * 
	 * @return 数据索引，-1表示未找到
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public int find(String key, E data) {
		return getList(key).indexOf(data);
	}
	
	/**
	 * 查找Left链表数据
	 * 
	 * @param data	数据
	 * 
	 * @return 数据索引，-1表示未找到
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public int findLeft(E data) {
		return find(LEFT, data);
	}
	
	/**
	 * 查找Center链表数据
	 * 
	 * @param data	数据
	 * 
	 * @return 数据索引，-1表示未找到
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public int findCenter(E data) {
		return find(CENTER, data);
	}
	
	/**
	 * 查找Right链表数据
	 * 
	 * @param data	数据
	 * 
	 * @return 数据索引，-1表示未找到
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public int findRight(E data) {
		return find(RIGHT, data);
	}
	
	/**
	 * 查找链表数据
	 * 
	 * @param key	链表KEY
	 * @param index	索引
	 * 
	 * @return	索引数据
	 * 
	 *  @throws RuntimeException 索引越界：index < 0 || index >= size
	 *  
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public E get(String key, int index) {
		return getList(key).get(index);
	}
	
	/**
	 * 查找Left链表数据
	 * 
	 * @param index	索引
	 * 
	 * @return	索引数据
	 * 
	 *  @throws RuntimeException 索引越界：index < 0 || index >= size
	 *  
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public E getLeft(int index) {
		return get(LEFT, index);
	}
	
	/**
	 * 查找Center链表数据
	 * 
	 * @param index	索引
	 * 
	 * @return	索引数据
	 * 
	 *  @throws RuntimeException 索引越界：index < 0 || index >= size
	 *  
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public E getCenter(int index) {
		return get(CENTER, index);
	}
	
	/**
	 * 查找Right链表数据
	 * 
	 * @param index	索引
	 * 
	 * @return	索引数据
	 * 
	 *  @throws RuntimeException 索引越界：index < 0 || index >= size
	 *  
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public E getRight(int index) {
		return get(RIGHT, index);
	}
	
	/**
	 * 遍历
	 * 
	 * @param fn	消费者：fn(data)
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	public void forEach(Consumer<? super E> fn) {
		// 主数据
		if (data != null) {
			fn.accept(data);
		}
		// 链表集
		for (SingleLinkedList<E> list : map.values()) {
			list.forEach(fn);
		}
	}

	/**
	 * 打印
	 * 
	 * @return
	 *
	 * @author 延晓磊
	 *
	 * @since 2020年7月24日
	 */
	@Override
	public String toString() {
		return "data = " + data + ", " + "map = " + map;
	}
	
	
}
